/*************************************************************************************************/
/**
    \file serie.cpp
    \brief A generic&simple module that handles a serial port

    Serial port service is provided through QextSerialPort class library
    DSII subject.

    \author Angel Perles
    \date  2011-02-05
*/

#include "serie.h"

#include <QtDebug>

#include <string.h>
#include <stdio.h>

static bool connection_ready = false;
static QextSerialPort *port;                    /* object that will handle the serial port */

/*************************************************************************************************/
/**
  \brief Opens a serial port

  \param port_name name of the device that provides access to a given serial port
  \retval true if port succesfully openned
  \retval false if port can not be openned

  Example:
  \verbatim
      if (serie_openConnection("COM1")) {
            printf("Port openned.");
      } else {
            printf("Error openning the port");
      }
   \endverbatim

*/
bool serie_openConnection(const char *port_name) {

    qDebug("intentando abrir...");

    static bool port_created = false;
    // crear el objeto de comunicaciones la primera vez que se entra aquí
    if (port_created == false) {
        port = new QextSerialPort();
        port->setQueryMode(QextSerialPort::Polling);  // modo mas sencillo
        port_created = true;
    }

    // if connected, then close before
    if (connection_ready) {
        serie_closeConnection();
        connection_ready = false;
    }

    // set port configuration
    port->setPortName(port_name);

    port->setBaudRate (BAUD9600);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_1);
    port->setParity(PAR_NONE);
    port->setFlowControl(FLOW_OFF);

    qDebug("puerto seteado");

    if (port->open(QextSerialPort::ReadWrite)) {
        connection_ready = true;
        qDebug("abierto!!!\n");
    } else {
        connection_ready = false;
        qDebug("vaya, esto CASCA\n");
    }

    return(connection_ready);
}

/*************************************************************************************************/
/**
  \brief Closes the serial port ... if it is open

  Example:
  \verbatim
      serie_closeConnection();
   \endverbatim

*/
void serie_closeConnection(void) {

    if (connection_ready) {
        port->close();
    }

    connection_ready = false;

}

/*************************************************************************************************/
/**
  \brief Sends strings of text to the device

  This functions is non-blocking, so it returns inmediately and no waits until data is sent to the device

  \param cad pointer to a null-terminated standard C string

  Example:
  \verbatim
      serie_sendStr("Les coques amb tomaca estan molt bones\x0D");
   \endverbatim

*/
void serie_sendStr(const char *cad) {

    if (connection_ready) {
        port->write(cad);
    } else {
        qDebug("Intentando transmitir sin el puerto listo");
    }
}

/*************************************************************************************************/
/**
  \brief Sends a given number of to the device

  This functions is non-blocking, so it returns inmediately and no waits until data is sent to the device

  \param dat pointer to data
  \param len number of bytes to be sent

  Example:
  \verbatim
      unsigned char dades[] = {35,49,110,69};

      serie_sendData(dades, 4);
   \endverbatim
*/
void serie_sendData(const char *dat, int len) {

    if (connection_ready) {
        port->write(dat, len);
    } else {
        qDebug("Intentando transmitir sin el puerto listo");
    }
}

/*************************************************************************************************/
/**
  \brief Receives the data that the devices sends to the host

  This functions is non-blocking, so it returns inmediately and no waits if data is not available

  \param destination pointer where data buyes will be put
  \param max_data maximum number of bytes that can be received, remaing data is keept in device's buffer

  \returns number of received bytes, or 0 if nothing received

  Example:
  \verbatim
      unsigned char buffer[10000];
      int num_bytes;

      num_bytes = serie_receiveData(buffer, 10000);
      if (num_bytes > 0) {
            printf("Received %d byes\n", num_bytes);
      }
   \endverbatim

*/
int serie_receiveData(char *destination, int max_data) {

    //const char *test="prova\x0D\x0A";
    //ProcessReceivedData(test);

    int num_bytes;

    if (!connection_ready) {
        return(0);
    }

    num_bytes = port->bytesAvailable();

    /* read data if something has arrived */
    if (num_bytes > 0) {
        if (num_bytes > max_data) {
            num_bytes = max_data;
        }
        port->read((char *)destination, num_bytes);
    }

    return(num_bytes);
}

/* FIN */
